package com.corpgovernment.travelstandard.controller;

import cn.hutool.core.lang.Tuple;
import com.corpgovernment.api.organization.model.post.PostVo;
import com.corpgovernment.api.travelstandard.enums.*;
import com.corpgovernment.api.travelstandard.vo.*;
import com.corpgovernment.api.travelstandard.vo.request.TravelStandardOverFlow2Request;
import com.corpgovernment.api.travelstandard.vo.request.TravelStandardShowRequest;
import com.corpgovernment.api.travelstandard.vo.request.TravelStandardSoaRequestListVo;
import com.corpgovernment.api.travelstandard.vo.response.FlightTravelStandardShowTextResponse;
import com.corpgovernment.common.base.BaseUserInfo;
import com.corpgovernment.common.base.JSONResult;
import com.corpgovernment.common.common.CorpBusinessException;
import com.corpgovernment.common.utils.DateUtil;
import com.corpgovernment.common.utils.Null;
import com.corpgovernment.organization.constant.CommonConst;
import com.corpgovernment.organization.constant.OrganizationResponseCodeEnum;
import com.corpgovernment.organization.service.IPostService;
import com.corpgovernment.travelstandard.entity.db.TravelStandardPost;
import com.corpgovernment.travelstandard.impl.MbTravelstandFlightCabinService;
import com.corpgovernment.travelstandard.impl.MbTravelstandFlightService;
import com.corpgovernment.travelstandard.impl.MbTravelstandFlightTimeService;
import com.corpgovernment.travelstandard.impl.MbTravelstandReasonCodeService;
import com.corpgovernment.travelstandard.impl.TravelStandardPostService;
import com.corpgovernment.travelstandard.utils.BeanConverUtil;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.generic.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 国内机票差标增删查改
 */
@RestController
@RequestMapping("flightTravelStandardManage")
public class FlightTravelStandardManageController {

    private final static String FLIGHT_TRAVEL_STANDARD_DEFAULT_NAME = "机票差旅标准";

    @Autowired
    private TravelStandardPostService standPostService;
    @Autowired
    private IPostService postService;
    @Autowired
    private MbTravelstandFlightService travelstandFlightService;
    @Autowired
    private MbTravelstandReasonCodeService travelstandReasonCodeService;
    @Autowired
    private MbTravelstandFlightTimeService travelstandFlightTimeService;
    @Autowired
    private MbTravelstandFlightCabinService standFlightCabinService;

    /**
     * 差标属于公司，不属于部门
     * 新增机票差标
     * 请求json：{title（机票名称）: "123", orgid（组织id）: "zjiXyTVVmY"}
     * @return
     */
    @RequestMapping("toAdd")
    public JSONResult toAddFlightTravelStandard(@RequestBody FlightTravelStandardManageVo flightTravelStandardManageVo ) {
        String title = flightTravelStandardManageVo.getTitle();
        //获取机票差标名称
        if (StringUtils.isBlank(title)) {
            title = FLIGHT_TRAVEL_STANDARD_DEFAULT_NAME;
        }
        //获取公司id
        String orgId = flightTravelStandardManageVo.getOrgId();
        if (StringUtils.isBlank(orgId)) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.ORG_ID_NULL);
        }
        MbTravelstandFlightVo travelstandFlightVo = new MbTravelstandFlightVo(
                null,
                orgId,
                title,
                FlightSwitchEnum.ClassDiscountSwitch.N.getCode(),
                ClazzEnum.Y.getCode(),
                ClazzEnum.Y.getCode(),
                new BigDecimal(8),
                ControlTypeEnum.F.getCode(),
                FlightSwitchEnum.LowpriceSwitch.N.getCode(),
                120,
                DateUtil.stringToDate("00:00",DateUtil.DF_HM),
                DateUtil.stringToDate("23:59",DateUtil.DF_HM),
                ControlTypeEnum.F.getCode(),
                FlightSwitchEnum.MileageSwitch.N.getCode(),
                800,
                ControlTypeEnum.F.getCode(),
                FlightSwitchEnum.AdvancedbookSwitch.N.getCode(),
                3,
                ControlTypeEnum.F.getCode(),
                FlightSwitchEnum.TimeSwitch.N.getCode(),
                TimeChooseTypeEnum.C.getCode(),
                ControlTypeEnum.F.getCode()
        );
        travelstandFlightVo.setAmountControlSwitch(FlightSwitchEnum.AmountControlSwitch.N.getCode());
        travelstandFlightVo.setAmountControlNum(100);
        travelstandFlightVo.setAmountControlType(ControlTypeEnum.F.getCode());

        travelstandFlightVo.setLowpriceTransferNeedCompare(CommonConst.FALSE);
        travelstandFlightVo.setAirportComparePrice(CommonConst.FALSE);
        travelstandFlightVo.setLowpriceFloatType(FlightSwitchEnum.LowPriceFloatTypeSwitch.A.getCode());
        travelstandFlightVo.setLowpriceFloatAmount(0);
        travelstandFlightVo.setLowpriceFloatNum(0);
        travelstandFlightVo.setAirportComparePrice(CommonConst.FALSE);
        travelstandFlightVo.setProtocolPriceSwitch(FlightSwitchEnum.ProtocolPriceSwitch.N.getCode());
        travelstandFlightVo.setProtocolPriceControlType(ControlTypeEnum.F.getCode());
        travelstandFlightVo.setProductSwitch("E");
        travelstandFlightVo.setProtocolPriceSwitch(FlightSwitchEnum.ProtocolPriceSwitch.N.getCode());
        travelstandFlightVo.setProtocolPriceControlType(ControlTypeEnum.F.getCode());
        travelstandFlightService.insertFlightTravelStandard(travelstandFlightVo);
        List<MbTravelstandReasonCodeVo> travelstandReasonCodeVos = travelstandReasonCodeService.list(new MbTravelstandReasonCodeVo().setTsId(travelstandFlightVo.getId()).setTsType(TravelStandardTypeEnum.Flight.getCode()));
        Map<String,Object> returnMap = new HashMap<>(1);
        List<MbTravelstandFlightTimeVo> mbTravelstandFlightTimeVos = travelstandFlightTimeService.list(new MbTravelstandFlightTimeVo().setTsFlightId(travelstandFlightVo.getId()));
        List<MbTravelstandFlightCabinVo> standFlightCabinVos = standFlightCabinService.list(
                new MbTravelstandFlightCabinVo().setTsFlightId(travelstandFlightVo.getId()).setTsType(TravelStandardTypeEnum.Flight.getCode()));
        returnMap.put("domAirTicket", BeanConverUtil.travelstandFlightVoToFlightTravelStandardManageVo(travelstandFlightVo,
                null, travelstandReasonCodeVos,mbTravelstandFlightTimeVos, standFlightCabinVos));
        return JSONResult.success(returnMap);
    }

    /**
     * 更新机票差标属性
     * @param vo
     * @return
     */
    @RequestMapping("save")
    public JSONResult updateFlightTravelStandardProperty(@RequestBody FlightTravelStandardManageVo vo) {
        travelstandFlightService.updateFlightTravelStandardProperty(vo);
        return JSONResult.ok();
    }

    /**
     * 更新差标名称
     */
    @RequestMapping("updateStandardName")
    public JSONResult updateStandardName(@RequestBody FlightTravelStandardManageVo travelStandardManageVo) {
        String id = travelStandardManageVo.getId();
        if (StringUtils.isBlank(id)){
            throw new CorpBusinessException(OrganizationResponseCodeEnum.PARAMS_IS_NULL, "id");
        }
        String title = travelStandardManageVo.getTitle();
        if (StringUtils.isBlank(title)){
            throw new CorpBusinessException(OrganizationResponseCodeEnum.PARAMS_IS_NULL, "title");
        }
        travelstandFlightService.updateStandardName(Long.valueOf(id),title);
        return JSONResult.ok();
    }

    /**
     * 删除机票差标
     * @return
     */
    @RequestMapping("delete")
    public JSONResult deleteFlightTravelStandard(@RequestBody FlightTravelStandardManageVo travelStandardManageVo) {
        String id = travelStandardManageVo.getId();
        if (StringUtils.isBlank(id)) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.PARAMS_IS_NULL, "id");
        }
        travelstandFlightService.deleteFlightTravelStandard(Long.valueOf(id));
        return JSONResult.ok();
    }

    /**
     * 获取全部机票差标
     *
     * @return
     */
    @RequestMapping("get")
    public JSONResult getFlightTravelStandard(@RequestBody FlightTravelStandardManageVo travelStandardManageVo) {
        String orgId = travelStandardManageVo.getOrgId();
        if (StringUtils.isBlank(orgId)) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.ORG_ID_NULL);
        }
        //通过soa接口获取全部岗位
        List<PostVo> posts = postService.listPostByOrgId(orgId);
        //已被选岗位
        List<TravelStandardPostVo> travelStandardPostVos = standPostService.selectByTsTypeAndOrgId(TravelStandardTypeEnum.Flight.getCode(), orgId);
        List<Long> jobScope = new ArrayList<>();
        for (TravelStandardPostVo travelStandardPostVo : travelStandardPostVos) {
            jobScope.add(travelStandardPostVo.getPostid());
        }
        //该组织下下所有机票差标
        List<FlightTravelStandardManageVo> domAirTicket = travelstandFlightService.listFlightTravelStandard(new MbTravelstandFlightVo(){{
            setOrgId(orgId);
        }});
        Map<String,Object> returnMap = new HashMap<>();
        returnMap.put("domAirTicket", domAirTicket);
        returnMap.put("jobScopeSelectList", jobScope);
        returnMap.put("jobScopeAllList", posts);
        return JSONResult.success(returnMap);
    }


    /**
     * 更新RC
     * @param rcListVo 传输对象
     * @return
     */
    @RequestMapping("updateRc")
    public JSONResult updateRc(@RequestBody RCListVo rcListVo) {
        rcListVo.setTsType(TravelStandardTypeEnum.Flight.getCode());
        travelstandReasonCodeService.updateTravelstandReasonCode(rcListVo);
        return JSONResult.ok();
    }

    /**
     * SOA-根据uid、orgId/tsId查询机票差标
     * @param travelStandardSoaRequestVo
     * @return
     */
    @RequestMapping("getFlightTravelStandard")
    public JSONResult<FlightTravelStandardSoaVo> getFlightTravelStandard(@RequestBody TravelStandardSoaRequestVo travelStandardSoaRequestVo) {
        Long tsId = null;
        if (!StringUtils.isBlank(travelStandardSoaRequestVo.getTsId())){
            tsId = Long.valueOf(travelStandardSoaRequestVo.getTsId());
        } else {
            Long postId = null;
            if (Objects.nonNull(travelStandardSoaRequestVo.getPostId()) && travelStandardSoaRequestVo.getPostId() > 0){
                postId = travelStandardSoaRequestVo.getPostId();
            }else{
                String userId = travelStandardSoaRequestVo.getUserId();
                if (StringUtils.isBlank(userId)) {
                    return JSONResult.errorMsg("没有userId!");
                }
                String orgId = travelStandardSoaRequestVo.getOrgId();
                if (StringUtils.isBlank(orgId)) {
                    return JSONResult.errorMsg("没有orgId!");
                }
                PostVo postVo = postService.listPostByUidAndOrgId(userId, orgId);
                //判断岗位是否存在
                if (postVo == null){
                    return JSONResult.ok();
                }
                postId = postVo.getId();
            }

            TravelStandardPostVo vo = new TravelStandardPostVo();
            vo.setPostid(postId);
            vo.setTstype(TravelStandardTypeEnum.Flight.getCode());
            List<TravelStandardPost> travelStandardPostVos = standPostService.list(vo);
            //判断该岗位下是否关联了差标
            if (travelStandardPostVos == null || travelStandardPostVos.size() == 0) {
                return JSONResult.ok();
            }
            TravelStandardPost travelStandardPost = travelStandardPostVos.get(0);
            tsId = travelStandardPost.getTsid();
        }
        MbTravelstandFlightVo mbTravelstandFlightVo = travelstandFlightService.get(tsId);
        //判断该差标是否存在
        if (mbTravelstandFlightVo == null){
            return JSONResult.ok();
        }
        //获得差标关联的RC
        List<MbTravelstandReasonCodeVo> travelstandReasonCodeVos = travelstandReasonCodeService.list(
                new MbTravelstandReasonCodeVo()
                        .setTsId(mbTravelstandFlightVo.getId())
                        .setTsType(TravelStandardTypeEnum.Flight.getCode())
        );
        //获得差标关联的时间信息
        List<MbTravelstandFlightTimeVo> mbTravelstandFlightTimeVos = travelstandFlightTimeService.list(new MbTravelstandFlightTimeVo().setTsFlightId(mbTravelstandFlightVo.getId()));

        List<MbTravelstandFlightCabinVo> standFlightCabinVos = standFlightCabinService.list(
                new MbTravelstandFlightCabinVo().setTsFlightId(mbTravelstandFlightVo.getId()).setTsType(TravelStandardTypeEnum.Flight.getCode()));

        FlightTravelStandardSoaVo flightTravelStandardSoaVo = BeanConverUtil.travelstandFlightVoToFlightTravelStandardSoaVo(
                mbTravelstandFlightVo,
                travelstandReasonCodeVos,
                mbTravelstandFlightTimeVos,
                standFlightCabinVos
        );
        flightTravelStandardSoaVo.setProductSwitch(mbTravelstandFlightVo.getProductSwitch());
        return JSONResult.success(flightTravelStandardSoaVo);
    }

    @RequestMapping("getFlightTravelStandardList")
    JSONResult<Map<String,FlightTravelStandardSoaVo>> getFlightTravelStandardList(@RequestBody TravelStandardSoaRequestListVo travelStandardSoaRequestVo) {
        if (travelStandardSoaRequestVo == null || CollectionUtils.isEmpty(travelStandardSoaRequestVo.getRequestVoList())){
            return new JSONResult<>(Collections.emptyMap());
        }
        return new JSONResult<>(travelStandardSoaRequestVo.getRequestVoList().stream().map(t -> {
            JSONResult<FlightTravelStandardSoaVo> response = this.getFlightTravelStandard(t);
            if (response != null && response.getData() != null){
                return new Tuple(t.getUserId(), response.getData());
            }
            return new Tuple(t.getUserId(), response.getData());
        }).collect(Collectors.toMap(t->t.get(0), t->t.get(1), (t1,t2)->t1)));

    }
    /**
     * APP-特定文本格式展示个人机票差标
     * @return
     */
    @RequestMapping("travelStandardShow")
    public JSONResult<FlightTravelStandardShowVo> travelStandardShow(@RequestBody(required = false) TravelStandardShowRequest travelStandardShowRequest, BaseUserInfo baseUserInfo) {
        String orgId;
        String uid;
        Long postId = null;
		if (travelStandardShowRequest == null) {
			orgId = baseUserInfo.getOrgId();
			uid = baseUserInfo.getUid();
		} else {
			orgId = travelStandardShowRequest.getPolicyOrgId();
			uid = travelStandardShowRequest.getPolicyId();
			if (StringUtils.isBlank(orgId)) {
				orgId = baseUserInfo.getOrgId();
			}
			if (StringUtils.isBlank(uid)) {
				uid = baseUserInfo.getUid();
			}
			if (Objects.nonNull(travelStandardShowRequest.getPostId())){
                postId = travelStandardShowRequest.getPostId();
            }
        }
        Long trafficId = Optional.ofNullable(travelStandardShowRequest).map(TravelStandardShowRequest::getTrafficId).orElse(null);
        return travelstandFlightService.flightTravelStandardShow(orgId, uid, postId, trafficId, Null.or(travelStandardShowRequest, TravelStandardShowRequest::getToken));
    }

    /**
     * APP-根据code展示超标的描述
     * @return
     */
    @RequestMapping("travelStandardOverFlow2")
    public JSONResult<List<String>> travelStandardOverFlow2(@RequestBody TravelStandardOverFlow2Request travelStandardOverFlow2Request) {
        return travelstandFlightService.flightTravelStandardOverflow2(travelStandardOverFlow2Request);
    }

    /**
     * SOA-展示个人机票差标
     *
     * @return
     */
    @RequestMapping("flightTravelStandardShowText")
    public JSONResult<FlightTravelStandardShowTextResponse> flightTravelStandardShowText(@RequestBody TravelStandardSoaRequestVo travelStandardSoaRequestVo) {
        return travelstandFlightService.flightTravelStandardShowText(travelStandardSoaRequestVo.getUserId(),travelStandardSoaRequestVo.getOrgId(),travelStandardSoaRequestVo.getStartDate());
    }

    /**
     * SOA-展示个人机票差标
     */
    // todo
    @PostMapping("flightTravelStandardShowSoa")
    public JSONResult<FlightTravelStandardShowVo> flightTravelStandardShowSoa(@RequestBody TravelStandardSoaRequestVo travelStandardSoaRequestVo) {
        return travelstandFlightService.flightTravelStandardShow(travelStandardSoaRequestVo.getOrgId(), travelStandardSoaRequestVo.getUserId(), travelStandardSoaRequestVo.getPostId(),travelStandardSoaRequestVo.getTrafficId(), Null.or(travelStandardSoaRequestVo, t->t.getToken()));
    }

}
